
#include "lg.h"

#define LG2D_CORE

#include "lg2d_shape.h"
#include "lg2d_scene.h"

static struct {
	LGMaterial* material;
}ctx;

static void
pushVertex(LG2DShape* shape, LG2DPoint* vs,
	unsigned vcount, unsigned* indexs, unsigned icount) {
	unsigned offset = lgGetListTotal(shape->points);
	for (unsigned i = 0; i < icount; i++) {
		indexs[i] += offset;
	}
	lgPushList(shape->indexs, indexs, icount);
	lgPushList(shape->points, vs, vcount);
}

static void
drawShape(LG2DScene* scene, LG2DObj* obj) {
	LG2DShape* shape = (LG2DShape*)obj;
	unsigned* indexs;
	unsigned count;
	lgBeginList(shape->indexs);
	while (lgNextList(shape->indexs, &indexs, &count)) {
		lg2dPushSceneIndexs(scene, indexs, count);
	}
	LG2DPoint* vs;
	lgBeginList(shape->points);
	while (lgNextList(shape->points, &vs, &count)) {
		lg2dPushScenePoints(scene,
			vs, count, &shape->obj.transform);
	}
	lg2dPushSceneCmd(scene, ctx.material, lgGetListTotal(shape->indexs));
}

static void
freeShape(LGRef* ref) {
	LG2DShape* shape = (LG2DShape*)ref;
	lgFreeList(shape->points);
	lgFreeList(shape->indexs);
}

LG2D_API LG2DShape*
lg2dNewShape() {
	if (!ctx.material) {
		LGShader* shader = lgNewStdShader(LGSTD_BASE_COLOR_SHADER);
		ctx.material = lgNewMaterial(shader);
		lgRetainRef(ctx.material);
	}
	LG2DShape* shape = lg2dNewExtendObj(sizeof(LG2DShape), freeShape);
	LGVector color = { 1.f, 1.f, 1.f, 1.f };
	shape->obj.draw = drawShape;
	shape->color = color;
	shape->points = lgNewList(sizeof(LG2DPoint), 8);
	shape->indexs = lgNewList(sizeof(unsigned), 16);
	return shape;
}


LG2D_API void
lg2dClearShape(LG2DShape* shape) {
	lgClearList(shape->points);
	lgClearList(shape->indexs);
}

LG2D_API void
lg2dShapeColor(LG2DShape* shape, LGVector* color) {
	shape->color = *color;
}
LG2D_API void
lg2dShapeRect(LG2DShape* shape, LGFloat rect[4]) {
	LGVector* color = &shape->color;
	LGFloat x = rect[0];
	LGFloat y = rect[1];
	LGFloat w = rect[2];
	LGFloat h = rect[3];
	unsigned indexs[] = { 0, 1, 2, 1, 2, 3 };
	LG2DPoint vs[] = {
		{{ x, y + h, 0.f, 1.f}, *color, {0.f, 0.f, 0.f, 0.f},},
		{{x + w, y + h, 0.f, 1.f}, *color, {1.f, 0.f, 0.f, 0.f},},
		{{x, y, 0.f, 1.f},  *color, {0.f, 1.f, 0.f, 0.f},},
		{{x + w, y, 0.f, 1.f}, *color, {1.f, 1.f, 0.f, 0.f},},
	};
	pushVertex(shape, vs, 4, indexs, 6);
}